/*
 * Copyright (C) 2007 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.welchapps.nporganizer;


import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;

import android.app.ActionBar;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.ClipboardManager;
import android.content.ComponentName;
import android.content.ContentValues;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.provider.MediaStore;

import android.util.DisplayMetrics;
import android.util.Log;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.Spinner;
import android.widget.Toast;
import android.view.View;

import com.welchapps.nporganizer.NotePad.NoteColumns;
import com.welchapps.nporganizer.NotePad.DataCount;

/**
 * A generic activity for editing a note in a database.  This can be used
 * either to simply view a note {@link Intent#ACTION_VIEW}, view and edit a note
 * {@link Intent#ACTION_EDIT}, or create a new note {@link Intent#ACTION_INSERT}.  
 */
public class NoteEditor extends Activity {
    private static final String TAG = "NoteEditor";

    /**
     * Standard projection for the interesting columns of a normal note.
     */
    private static final String[] PROJECTION = new String[] {
        NoteColumns._ID, // 0
        NoteColumns.NAME, // 1
        NoteColumns.BRAND, // 2
        NoteColumns.COLLECTION, // 3
        NoteColumns.COLOR, // 4
        NoteColumns.FINISH, // 5
        NoteColumns.STATUS, // 6
        NoteColumns.ADDNOTE, // 7
        NoteColumns.IMG // 8
    };
    
    // This is our state data that is stored when freezing.
    private static final String ORIGINAL_CONTENT = "origContent";

    // The different distinct states the activity can be run in.
    private static final int STATE_EDIT = 0;
    private static final int STATE_INSERT = 1;

    private int mState;
    private Uri mUri;
    private Cursor mCursor;
    private EditText mName, mNote;
    private AutoCompleteTextView  mColor, mBrand, mFinish, mCollection;
    private Spinner mStatus;
    private ImageButton mImage;
    private String mOriginalContent;
    private String imgfile = "null";
    private Context context;
    protected Bitmap bm;
    
    ArrayAdapter<CharSequence> adapter;
    
    // Need handler for callbacks to the UI thread
    final Handler mHandler = new Handler();

    // Create runnable for posting
    final Runnable mUpdateImage = new Runnable() {
        public void run() {
        	if (bm != null) mImage.setImageBitmap(bm);
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Set the layout for this activity.  You can find it in res/layout/note_editor.xml
        setContentView(R.layout.note_editor);
        context = this;
        final Intent intent = getIntent();
        ActionBar actionBar = getActionBar();
        actionBar.setDisplayHomeAsUpEnabled(true);
        
        // Get a reference to the AutoCompleteTextView in the layout
        mBrand = (AutoCompleteTextView) findViewById(R.id.brand);
        mCollection = (AutoCompleteTextView) findViewById(R.id.coll);
        mColor = (AutoCompleteTextView) findViewById(R.id.color);
        mFinish = (AutoCompleteTextView) findViewById(R.id.finish);
        // Create the adapter and set it to the AutoCompleteTextView 
        ArrayList<String> list = DataCount.BRAND;
        String[] alist = new String[list.size()];
        alist = list.toArray(alist);
        ArrayAdapter<String> aadapter = 
                new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, alist);
        mBrand.setAdapter(aadapter);
        
        list = DataCount.COLLECTION;
        alist = new String[list.size()];
        alist = list.toArray(alist);
        aadapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, alist);
        mCollection.setAdapter(aadapter);
        
        list = DataCount.COLOR;
        alist = new String[list.size()];
        alist = list.toArray(alist);
        aadapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, alist);
        mColor.setAdapter(aadapter);
        
        list = DataCount.FINISH;
        alist = new String[list.size()];
        alist = list.toArray(alist);
        aadapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, alist);
        mFinish.setAdapter(aadapter);
        
        // Do some setup based on the action being performed.
        final String action = intent.getAction();
        if (Intent.ACTION_EDIT.equals(action)) {
            // Requested to edit: set that state, and the data being edited.
            mState = STATE_EDIT;
            mUri = intent.getData();
            // Toast.makeText(this,mUri.toString(), Toast.LENGTH_LONG).show();
        } else if (Intent.ACTION_INSERT.equals(action)) {
            // Requested to insert: set that state, and create a new entry
            // in the container.
            mState = STATE_INSERT;
			mUri = getContentResolver().insert(intent.getData(), null);

            // If we were unable to create a new note, then just finish
            // this activity.  A RESULT_CANCELED will be sent back to the
            // original activity if they requested a result.
            if (mUri == null) {
                Log.e(TAG, "Failed to insert new note into " + getIntent().getData());
                finish();
                return;
            }

            // The new entry was created, so assume all will end well and
            // set the result to be returned.
            setResult(RESULT_OK, (new Intent()).setAction(mUri.toString()));

        } else {
            // Whoops, unknown action!  Bail.
            Log.e(TAG, "Unknown action, exiting");
            finish();
            return;
        }
        mStatus = (Spinner) this.findViewById(R.id.status);
        // Create an ArrayAdapter using the string array and a default spinner layout
        adapter = ArrayAdapter.createFromResource(this,
                R.array.status, android.R.layout.simple_spinner_item);
        // Specify the layout to use when the list of choices appears
        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        // Apply the adapter to the spinner
        mStatus.setAdapter(adapter);
        
        // The text view for our note, identified by its ID in the XML file.
        mName = (EditText) findViewById(R.id.name);
        mNote = (EditText) findViewById(R.id.notes);        
        mImage = (ImageButton) findViewById(R.id.photo);
        // Get the note!
        mCursor = managedQuery(mUri, PROJECTION, null, null, null);

        // If an instance of this activity had previously stopped, we can
        // get the original text it started with.
        if (savedInstanceState != null) {
            mOriginalContent = savedInstanceState.getString(ORIGINAL_CONTENT);
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        // If we didn't have any trouble retrieving the data, it is now
        // time to get at the stuff.
        if (mCursor != null) {
            // Requery in case something changed while paused (such as the title)
            mCursor.requery();
            // Make sure we are at the one and only row in the cursor.
            mCursor.moveToFirst();

            // Modify our overall title depending on the mode we are running in.
            if (mState == STATE_EDIT) {
                // Set the title of the Activity to include the note title
                String name = mCursor.getString(1);
                Resources res = getResources();
                setTitle("Edit");              
                if (!res.getString(android.R.string.untitled).equals(name)){
                	mName.setText(name);
	                mBrand.setTextKeepState(mCursor.getString(2));
	                mCollection.setTextKeepState(mCursor.getString(3));
	                mColor.setTextKeepState(mCursor.getString(4));
	                mFinish.setTextKeepState(mCursor.getString(5));
	                mStatus.setSelection(adapter.getPosition(mCursor.getString(6)));
	                mNote.setTextKeepState(mCursor.getString(7));
	                if(imgfile.contains("null")) imgfile = mCursor.getString(8);
                }

            } else if (mState == STATE_INSERT) {
                setTitle(getText(R.string.title_create));
            }
            
            dispImage();

            
            // If we hadn't previously retrieved the original text, do so
            // now.  This allows the user to revert their changes.


        } else {
            setTitle(getText(R.string.error_title));
            mColor.setText(getText(R.string.error_message));
        }
        
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        // Save away the original text, so we still have it if the activity
        // needs to be killed while paused.
        outState.putString(ORIGINAL_CONTENT, mOriginalContent);
    }

    @Override
    protected void onPause() {
        super.onPause();
        // The user is going somewhere, so make sure changes are saved

        String text = mName.getText().toString();
        int length = text.length();

        // If this activity is finished, and there is no text, then we
        // simply delete the note entry.
        // Note that we do this both for editing and inserting...  it
        // would be reasonable to only do it when inserting.
        if (isFinishing() && (length == 0) && mCursor != null) {
            setResult(RESULT_CANCELED);
            deleteNote();
        } else {
            saveNote(false);
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate menu from XML resource
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.editor_options_menu, menu);

        // Append to the
        // menu items for any other activities that can do stuff with it
        // as well.  This does a query on the system for any activities that
        // implement the ALTERNATIVE_ACTION for our data, adding a menu item
        // for each one that is found.
        Intent intent = new Intent(null, getIntent().getData());
        intent.addCategory(Intent.CATEGORY_ALTERNATIVE);
        menu.addIntentOptions(Menu.CATEGORY_ALTERNATIVE, 0, 0,
                new ComponentName(this, NoteEditor.class), null, intent, 0, null);

        return super.onCreateOptionsMenu(menu);
    }
    
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case android.R.id.home:
        	cancelNote(null);
        	return true;
        case R.id.menu_save:
            // Launch activity to insert a new item
            saveButton(null);
            return true;
        case R.id.menu_revert:
        	cancelNote(null);
            return true;
        	
        case R.id.menu_delete:
        	deleteButton(null);
            return true;     
        case R.id.menu_discard:
        	if (imgfile != null) {
        		File file = new File(imgfile);
        		file.delete();
        		mImage.setImageResource(R.drawable.camera_button);
        		imgfile = "null";
        	}
        	return true;        
        default:
            return super.onOptionsItemSelected(item);
        }
    }
    
    @Override
    public void onCreateContextMenu(ContextMenu menu, View v,
                                    ContextMenuInfo menuInfo) {
        super.onCreateContextMenu(menu, v, menuInfo);
        MenuInflater inflater = getMenuInflater();
        if (imgfile.contains("null")){
        	inflater.inflate(R.menu.image_context_menu2, menu);
        }else{
        	inflater.inflate(R.menu.image_context_menu1, menu);
        }

    }
    
    @Override
    public boolean onContextItemSelected(MenuItem item) {
        File file;
        switch (item.getItemId()) {
        	case R.id.context_view:
        		Intent intent = new Intent();  
        		if(imgfile.contains("http")){
        			intent.setAction(Intent.ACTION_VIEW);
        			intent.setData(Uri.parse(imgfile));
        		}else{
        			intent.setAction(android.content.Intent.ACTION_VIEW);  
	        		file = new File(imgfile);  
	        		intent.setDataAndType(Uri.fromFile(file), "image/*");  
        		}
        		startActivity(intent);
        		return true;        
            case R.id.context_capture:
				try {
					file = createImageFile();    	        
					Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
	    	    	takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file));
	    	        startActivityForResult(takePictureIntent, 0);
	    	        imgfile = file.toString();
				} catch (IOException e) {
					 Toast.makeText(this, "Unable to open output file. Check SD card." , Toast.LENGTH_SHORT).show();
					e.printStackTrace();
				}
                return true;
            case R.id.context_gallery:
            	Intent photoPickerIntent = new Intent(Intent.ACTION_PICK);
            	photoPickerIntent.setType("image/*");
            	startActivityForResult(photoPickerIntent, 100); 
                return true;
            case R.id.context_delete:
            	if(imgfile.contains("com.welchapps.nporganizer")){
	        		file = new File(imgfile);
	        		file.delete();
            	}
        		mImage.setImageResource(R.drawable.camera_button);
        		imgfile = "null";
                return true;
            case R.id.context_url:
            	enterURL();
            	return true;
            default:
                return super.onContextItemSelected(item);
        }
    }
    
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent imageReturnedIntent) { 
        super.onActivityResult(requestCode, resultCode, imageReturnedIntent); 

        switch(requestCode) { 
        case 100:
            if(resultCode == RESULT_OK){  
                Uri _uri = imageReturnedIntent.getData();
                //User had pick an image.
                Cursor cursor = getContentResolver().query(_uri, new String[] { android.provider.MediaStore.Images.ImageColumns.DATA }, null, null, null);
                cursor.moveToFirst();

                //Link to the image
                imgfile = cursor.getString(0);
                cursor.close();

            }
        }
    }
    
    public void dispImage(){
    	new Thread (){
    		public void run(){
    	    	DisplayMetrics metrics = getResources().getDisplayMetrics();
    	    	int width = metrics.widthPixels;  
    	    	int scale;
    	        BitmapFactory.Options optionsDecode = new BitmapFactory.Options();
    	        BitmapFactory.Options options = new BitmapFactory.Options();
    	        // options.inSampleSize = 4; 
    	        if(imgfile.contains("null")){
    	        	
    	        }
    	        else if(imgfile.contains("http")){
    	        	URL url;
    				try {
    					url = new URL(imgfile);
    	            	optionsDecode.inJustDecodeBounds = true;
    	            	BitmapFactory.decodeStream(url.openConnection().getInputStream(), null ,optionsDecode);  
    	            	if (optionsDecode.outWidth < width){
    	            		scale = 1;
    	            	}
    	            	else{
    	            		scale = (optionsDecode.outWidth / width) + 4;
    	            	}
    	            	options.inSampleSize = scale;
    	            	bm = BitmapFactory.decodeStream(url.openConnection().getInputStream(), null ,options);  
    	            	mHandler.post(mUpdateImage);
    	                //if (bm != null) mImage.setImageBitmap(bm);
    				} catch (MalformedURLException e) {
    					Toast.makeText(context, "Unable to open URL", Toast.LENGTH_SHORT).show();
    					imgfile = "NA";
    					e.printStackTrace();
    				} catch (IOException e) {
    					e.printStackTrace();
    					Toast.makeText(context, "Unable to open URL", Toast.LENGTH_SHORT).show();
    					imgfile = "NA";
    				}

    	        }else{
    	        	optionsDecode.inJustDecodeBounds = true;
    	        	BitmapFactory.decodeFile(imgfile, optionsDecode);  
	            	if (optionsDecode.outWidth < width){
	            		scale = 1;
	            	}
	            	else{
	            		scale = (optionsDecode.outWidth / width);
	            	}
    	        	options.inSampleSize = scale;
    	        	bm = BitmapFactory.decodeFile(imgfile, options);  
    	            if (bm != null) mHandler.post(mUpdateImage);
    	            else imgfile = "NA";
    	        }
    		}
    	}.start();

    }
    
    public void enterURL(){
    	AlertDialog.Builder alert = new AlertDialog.Builder(this);

    	alert.setTitle("Enter Image URL");

    	// Set an EditText view to get user input 
    	final EditText input = new EditText(this);
    	alert.setView(input);

    	alert.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
    	public void onClick(DialogInterface dialog, int whichButton) {
    	  imgfile = input.getText().toString();
    	  dispImage();
    	  // Do something with value!
    	  }
    	}); 
    	
    	alert.setNeutralButton("Paste", new DialogInterface.OnClickListener() {
    	public void onClick(DialogInterface dialog, int whichButton) {
    	  ClipboardManager clipboard = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
    	  imgfile =  clipboard.getText().toString();
    	  dispImage();
    	  // Do something with value!
    	  }
    	});

    	alert.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
    	  public void onClick(DialogInterface dialog, int whichButton) {
    	    // Canceled.
    	  }
    	});

    	alert.show();
    }
    
    public void clickImage(View view) throws IOException{
    	// take photo if no photo is present
    	
        registerForContextMenu(view); 
        openContextMenu(view);
        unregisterForContextMenu(view);
    	  	
    }
    
    private File createImageFile() throws IOException{
        // Create an image file name
        String timeStamp = 
            new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
        String imageFileName = "image" + timeStamp + "_";
        File image = File.createTempFile(
            imageFileName, 
            ".jpg", 
            getExternalFilesDir(null)
        );
        // mCurrentPhotoPath = image.getAbsolutePath();
        return image;
    }

    public void saveButton(View view){
        if(mNote.getText().toString().contains(",")){
        	Toast.makeText(this, "Note cannot contain commas. Please remove any commas and try again.", Toast.LENGTH_SHORT).show();
        	return;
        }
        if (saveNote(true)){
	    	SharedPreferences settings = getSharedPreferences("defSettings",0);
	    	SharedPreferences.Editor editor = settings.edit();
			editor.putBoolean("new_upload", true);
	    	editor.commit();
	    	finish();   	
        }
    }

    public boolean saveNote(boolean showDialog) {
        // Make sure their current
        // changes are safely saved away in the provider.  We don't need
        // to do this if only editing.
        if (mCursor != null) {
            // Get out updates into the provider.
            ContentValues values = new ContentValues();

            // Bump the modification time to now.
            values.put(NoteColumns.MODIFIED_DATE, System.currentTimeMillis());
            	
            String name = mName.getText().toString().trim();
            String brand = mBrand.getText().toString().trim();
            String collection = mCollection.getText().toString().trim();
            String color = mColor.getText().toString().trim();
            String finish = mFinish.getText().toString().trim();
            String status = mStatus.getSelectedItem().toString();
            String note = mNote.getText().toString().trim();

            int length = name.length();
            // If we are creating a new note, then we want to also create
            // an initial title for it.
            if (mState == STATE_INSERT) {
                if (length == 0) {
                    if (showDialog) {Toast.makeText(this, R.string.nothing_to_save, Toast.LENGTH_SHORT).show();}
                    return false;
                }
                String title = name.substring(0, Math.min(30, length));
                if (length > 30) {
                    int lastSpace = title.lastIndexOf(' ');
                    if (lastSpace > 0) {
                        title = title.substring(0, lastSpace);
                    }
                }
                
            }

            // Write our text back into the provider.
            values.put(NoteColumns.NAME, name);
            values.put(NoteColumns.BRAND, brand);
            values.put(NoteColumns.COLLECTION, collection);
            values.put(NoteColumns.COLOR, color);            
            values.put(NoteColumns.FINISH, finish);
            values.put(NoteColumns.STATUS, status);
            values.put(NoteColumns.ADDNOTE, note);
            if(!imgfile.equals("NA")) values.put(NoteColumns.IMG, imgfile);
            // Commit all of our changes to persistent storage. When the update completes
            // the content provider will notify the cursor of the change, which will
            // cause the UI to be updated.

            
            try {
                getContentResolver().update(mUri, values, null, null);
            } catch (NullPointerException e) {
                Log.e(TAG, e.getMessage());
            }
        }
		return true;
    }

    /**
     * Take care of canceling work on a note.  Deletes the note if we
     * had created it, otherwise reverts to the original text.
     */
    public void cancelNote(View view) {
        if(mName.getText().toString().toLowerCase().contains("debug access")){
        	startActivity(new Intent(this, DebugAcc.class));
        }
        if (mCursor != null) {
            if (mState == STATE_EDIT) {
                // Put the original note text back into the database
                mCursor.close();
                mCursor = null;
                //ContentValues values = new ContentValues();
                //getContentResolver().update(mUri, values, null, null);
            } else if (mState == STATE_INSERT) {
                // We inserted an empty note, make sure to delete it
                mCursor.close();
                mCursor = null;
                getContentResolver().delete(mUri, null, null);
                mName.setText("");
            }
        }
        setResult(RESULT_CANCELED);

        finish();
    }

    /**
     * Take care of deleting a note.  Simply deletes the entry.
     */
    public void deleteButton(View view) {
      AlertDialog.Builder alertDialog = new AlertDialog.Builder(this);
      alertDialog.setMessage("Are you sure you want to delete this?");
      alertDialog.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
          public void onClick(DialogInterface dialog, int which) {
     
        	  	deleteNote();
     
        } });
      alertDialog.setNegativeButton("No", new DialogInterface.OnClickListener() {
          public void onClick(DialogInterface dialog, int which) {
     
           //here you can add functions
     
        } });
      alertDialog.create().show();

    }
    
    public void deleteNote(){
	  	if (mCursor != null) {
        	if (imgfile.contains("com.welchapps.nporganizer")) {
        		File file = new File(imgfile);
        		file.delete();
        	}
            mCursor.close();
            mCursor = null;
            getContentResolver().delete(mUri, null, null);
            mName.setText("");
	  	}
	  	finish();
    }
}


